﻿using System;
using System.Data.Common;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.IO;
using System.Xml.Linq;
using MDCAdminTool.Properties;
using System.Windows.Media;
using E4D.AppFabric.Entities.Engine;

namespace MDCAdminTool.Controls
{
    public partial class SystemRequirementsCheck : UserControl
    {
        #region Fiels & Properties
        public event EventHandler EndCheck;
        private DataCacheConfigSection dataCacheConfig;

        private bool _ConfigOk;
        private bool _ConnectionStringOk;
        private bool _PowerSheelOk;


        public bool ConfigOk
        {
            get { return _ConfigOk; }
            set
            {
                _ConfigOk = value;
                SetStat( rConfig , value );
            }
        }
        public bool ConnectionStringOk
        {
            get { return _ConnectionStringOk; }
            set
            {
                _ConnectionStringOk = value;
                SetStat( rConn , value );
            }
        }
        public bool PowerSheelOk
        {
            get { return _PowerSheelOk; }
            set
            {
                _PowerSheelOk = value;
                SetStat( rPowerShell , value );
            }
        }

        public bool IsRun { get; set; }
        public bool IsOk
        {
            get { return ConfigOk && ConnectionStringOk && PowerSheelOk; }
        }

        private CacheCluster _CacheCluster;
        #endregion

        public SystemRequirementsCheck()
        {
            InitializeComponent();
        }

        public void BeginRun()
        {
            IsRun = true;
            tbConfig.Text     = "Search the Distributed Cache Config File...";
            tbConn.Text       = "Test the Connection string...";
            tbPowerShell.Text = "Test the Power Shell...";

            rConfig.ClearValue( Rectangle.FillProperty );
            rConn.ClearValue( Rectangle.FillProperty );
            rPowerShell.ClearValue( Rectangle.FillProperty );

            StartProgressBar();
            Action func = 
              () =>
              {
                  CheckPowerShell();
                  CheckMdcConfigFile();
                  CheckConnString();
              };

            func.BeginInvoke( EndRun , func );
        }
        private void EndRun( IAsyncResult ar )
        {
            Action func = ar.AsyncState as Action;
            func.EndInvoke( ar );

            if ( EndCheck != null )
                EndCheck( this , EventArgs.Empty );

            if ( IsOk )
                this.Dispatcher.Invoke(
                    new Action( () => Visibility = Visibility.Collapsed ) );

            IsRun = false;
        }

        private void StartProgressBar()
        {
            pbConfig.Start();
            pbConn.Start();
            pbPowerShell.Start();
        }
        private void StopProgressBar()
        {
            pbConfig.Stop();
            pbConn.Stop();
            pbPowerShell.Stop();
        }

        private void CheckPowerShell()
        {
            _CacheCluster = new CacheCluster();

            try
            {
                using (var session = SessionFactory.getLocalSession())
                {
                    PowerSheelOk = true;
                    tbPowerShell.Dispatcher.Invoke(
                        new Action(() =>
                        {
                            //tbPowerShell.Foreground = new SolidColorBrush( Colors.Green );
                            tbPowerShell.Text = "PowerShell Test OK.";
                        }));
                }
            }
            catch (Exception)
            {
                PowerSheelOk = false;
                tbPowerShell.Dispatcher.Invoke(
                    new Action(() =>
                    {
                        //tbPowerShell.Foreground = new SolidColorBrush(Colors.Red);
                        tbPowerShell.Text = "Can't Open PowerShell.";
                    }));
            }
            pbPowerShell.Stop();
        }
        private void CheckConnString()
        {
            bool result = false;
            DbConnection conn = null;

            try
            {
                InitDataCacheConfig();

                var factory = DbProviderFactories.GetFactory( dataCacheConfig.Provider );
                conn = factory.CreateConnection();
                conn.ConnectionString = dataCacheConfig.ConnectionString;
                conn.Open();
                result = true;
            }
            catch ( Exception )
            {
                result = false;
            }
            finally
            {
                if ( conn != null )
                    conn.Dispose();
            }

            if ( result )
            {
                ConnectionStringOk = true;
                tbConn.Dispatcher.Invoke(
                     new Action( () => tbConn.Text = "Connection Test OK." ) );
            }
            else
            {
                ConnectionStringOk = false;
                tbConn.Dispatcher.Invoke(
                      new Action( () =>
                      {
                          //tbConn.Foreground = new SolidColorBrush( Colors.Red );
                          tbConn.Text = "Can't Open Connection to DB or Compact DB.";
                      } ) );
            }
            pbConn.Stop();

        }
        private void CheckMdcConfigFile()
        {
            if ( File.Exists( Settings.Default.DistributedCacheConfigFile ) )
            {
                ConfigOk = true;
                tbConfig.Dispatcher.Invoke(
                     new Action( () => tbConfig.Text = "Distributed Cache Config File Found." ) );
            }
            else
            {
                ConfigOk = false;
                tbConfig.Dispatcher.Invoke(
                     new Action( () =>
                     {
                         //tbConfig.Foreground = new SolidColorBrush( Colors.Red );
                         tbConfig.Text = "CDistributed Cache Config File Not Found.";
                     } ) );
            }
            pbConfig.Stop();
        }

        private void InitDataCacheConfig()
        {

            var config  = XElement.Load( Settings.Default.DistributedCacheConfigFile );
            XElement dcc = config.Descendants( "dataCacheConfig" ).First();
            if ( dcc != null )
            {
                dataCacheConfig = new DataCacheConfigSection
                                      {
                                          ClusterName   = dcc.Attribute( "clusterName" ).Value ,
                                          HostName      = dcc.Attribute( "hostName" ).Value ,
                                          CacheHostName = dcc.Attribute( "cacheHostName" ).Value ,
                                          Provider      = dcc.Element( "clusterConfig" ).Attribute( "provider" ).Value ,
                                          ConnectionString = dcc.Element( "clusterConfig" ).Attribute( "connectionString" ).Value
                                      };
            }

        }
        private void SetStat( Rectangle rec , bool stat )
        {
            this.Dispatcher.Invoke(
                new Action(
                    () =>
                    {
                        if ( stat )
                        {
                            rec.Style = this.FindResource( "Ok" ) as Style;
                        }
                        else
                        {
                            rec.Style = this.FindResource( "Bad" ) as Style;
                        }
                    } ) );
        }

        private void Close_Click( object sender , RoutedEventArgs e )
        {
            this.Visibility = Visibility.Collapsed;
            StopProgressBar();
        }
    }
}
